/*
 * @Author: 曹捷
 * @Date: 2019-08-21 20:52:05
 * @LastEditors: 曹捷
 * @LastEditTime: 2020-12-13 21:20:37
 * @Description: 封装  ajax API
 */
import { toLogin } from '@/app-modules/utils/user'
import { keyword } from './keyword'
import store from '@/store'
import sysConfig from '@/config/config'
import qs from 'qs'
class Http {
  constructor (options) {
    this.options = Object.assign(
      {
        loading: false, // 是否显示loading 提示框
        loadingText: 'Loading', //loading 提示框文字内容
        mask: true, //loading 提示框 是否显示透明蒙层，防止触摸穿透
        loadingStatus: true, //计算加载状态  当前是否有请求在加载，可适用于自定义展示loading效果和骨架效果等
        keyFilter: false, //是否进行关键词过滤
        timeout: 60000
      },
      options
    )
  }
  requestBefore (data, reqOptions = {}) {
    reqOptions = Object.assign({}, this.options, reqOptions)
    if (reqOptions.loading) {
      uni.showLoading({
        mask: reqOptions.mask,
        title: reqOptions.loadingText,
      })
    }
    let authParams = {}
    // 对外暴露 数据拦截处理
    if (sysConfig.ajax && sysConfig.ajax.requestBefore) {
      authParams = sysConfig.ajax.requestBefore(reqOptions)
    }
    return Object.assign(data, authParams)
  }
  /**
   * 请求结束
   * 判断是否还有请求在加载
   */
  requestEnd (header, config = {}) {
    let options = Object.assign({}, this.options, config)
    if (options.loadingStatus) {
      store.commit('endRequest', header.rqId)
    }
    if (options.loading) {
      uni.hideLoading()
    }
  }
  /**
   * 获取  统一的请求头信息
   */
  getHeader (config = {}) {
    let options = Object.assign({}, this.options, config)
    let userInfo = uni.getStorageSync('userInfo')
    let rqId =
      Math.random()
        .toString()
        .substr(3) +
      '_' +
      Date.now()
    let header = {
      rqId
    }
    // 计算加载状态
    if (options.loadingStatus) {
      store.commit('startRequest', rqId)
    }
    if (userInfo && userInfo.accessToken) {
      header.Authorization = userInfo.accessToken
      header.UserId = `${userInfo.userId}`
    }
    // 对外暴露 自定义可配置的响应体拦截处理
    if (sysConfig.ajax && sysConfig.ajax.getHeader) {
      return sysConfig.ajax.getHeader(config)
    }
    return header
  }

  /**
   * 请求成功 统一封装和判断response
   * @param {*} res
   * response 返回体
   * @param {*} resolve
   * 成功的回调
   * @param {*} fal
   * 失败的回调
   */
  responseSuccess (res, resolve, fal, hide = true) {
    // if (hide) {
    //   uni.hideLoading()
    // }
    // 对外暴露 自定义可配置的响应体拦截处理
    if (sysConfig.ajax && sysConfig.ajax.responseSuccess) {
      sysConfig.ajax.responseSuccess(res, resolve, fal)
      return
    }
    if (res.data && (res.data.code === '0000' || res.data.code === '000')) {
      resolve(res.data.data)
    } else if (res.data && res.data.code === '0005') {
      uni.removeStorageSync('userInfo')
      uni.showToast({
        title: '请重新登录',
        icon: 'none',
        duration: 2000,
      })
      toLogin()
      Promise.reject()
    } else if (res.data.code == 'LOGIN.001') {
      toLogin()
      fal(res.data)
    } else {
      if (res.data.code !== '0002') {
        uni.showToast({
          title: res.data.errorMsg,
          icon: 'none',
          duration: 2000,
        })
      }
      fal(res.data)
    }
  }
  responseFail (res) {
    uni.hideLoading()
    // 对外暴露 自定义可配置的响应体拦截处理
    if (sysConfig.ajax && sysConfig.ajax.responseFail) {
      sysConfig.ajax.responseFail(res)
      return
    }
    uni.showToast({
      title: '网络异常，请稍后重试',
      icon: 'none',
      duration: 2000,
    })
    return res
  }
  get (url, data = {}, config = {}) {
    let param = this.requestBefore(data, config)
    if (param == null) {
      return {}
    }
    return new Promise((resolve, fal) => {
      let header = this.getHeader(config)
      uni.request({
        url: `${url}`,
        data: param,
        timeout: this.options.timeout,
        header: header,
        success: (res) => {
          this.requestEnd(header, config)
          this.responseSuccess(res, resolve, fal)
        },
        fail: (res) => {
          this.requestEnd(header, config)
          fal(this.responseFail(res))
        },
      })
    })
  }
  post (url, data, config = {}) {
    let param = this.requestBefore(data, config)
    if (param == null) {
      return {}
    }
    return new Promise((resolve, fal) => {
      let header = this.getHeader(config)
      if (config.keyFilter) {
        let next = this.keyWordFilter(param, fal)
        if (next) {
          return
        }
      }
      uni.request({
        url: `${url}`,
        data: param,
        timeout: this.options.timeout,
        method: 'POST',
        header: Object.assign({ 'content-type': config.contentType || 'application/json' }, header),
        success: (res) => {
          this.requestEnd(header, config)
          this.responseSuccess(res, resolve, fal)
        },
        fail: (res) => {
          this.requestEnd(header, config)
          fal(this.responseFail(res))
        },
      })
    })
  }
  tableGet (url, data = {}, config = { method: 'get' }) {
    return this.tablePost(url, data, config)
  }
  tablePost (url, data = {}, config = { method: 'POST' }) {
    if (data.pageNum && data.pageNum > 1) {
      config = Object.assign({ loadingStatus: false }, config)
    }
    let param = this.requestBefore(data, config)
    if (param == null) {
      return {}
    }
    let header = this.getHeader(config)
    header = Object.assign(
      {
        'content-type': 'application/json',
      },
      header
    )
    return new Promise((resolve, fal) => {
      uni.request({
        url: `${url}`,
        data: param,
        timeout: this.options.timeout,
        method: config.method,
        header: header,
        success: (res) => {
          this.requestEnd(header, config)
          resolve(res.data)
        },
        fail: (res) => {
          this.requestEnd(header, config)
          fal(this.responseFail(res))
        },
      })
    })
  }
  upload (url, file = {}, formData = {}, config = {}) {
    let header = this.getHeader(config)
    return new Promise((resolve, fal) => {
      uni.uploadFile({
        url: url,
        filePath: file,
        name: 'headPortraitFile',
        header: header,
        formData: formData,
        success: (res) => {
          this.requestEnd(header, config)
          res.data = JSON.parse(res.data)
          this.responseSuccess(res, resolve, fal, false)
        },
        fail: (res) => {
          this.requestEnd(header, config)
          fal(this.responseFail(res))
        },
      })
    })
  }

  keyWordFilter (data, fal) {
    let key = ''
    Object.keys(data).forEach((element) => {
      if (Object.prototype.toString.call(data[element]).indexOf('String') !== -1) {
        let info = data[element]
        for (let i = 0; i < keyword.length; i++) {
          if (info.indexOf(keyword[i]) !== -1) {
            key = keyword[i]
            return
          }
        }
      }
    })
    if (key) {
      uni.showToast({
        title: '当前发布信息存在敏感词汇，请检查',
        icon: 'none',
        duration: 2000,
      })
      fal('存在敏感词汇' + key)
      return true
    }
    return false
  }
}
let getData = new Http()
export { Http, getData }
